#coding=utf-8
import re,time,subprocess,multiprocessing,time,os

logFile="/var/log/secure"
denyFile="/etc/hosts.deny"
ipPattern='\d*\.\d*\.\d*\.\d*'
advance=10
def denyDict():
  denyFileLines=open(denyFile).readlines()
  denyList={}
  for ip in  denyFileLines:
    if bool(re.search(ipPattern,ip)):
      denyList[re.search(ipPattern,ip).group()]=True
  return denyList

def monitoring():
  denyList=denyDict()
  failedList={}
  logFileRead=subprocess.Popen("tail -n 20 -f /var/log/secure",stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)
  for i in range(20):
    time.sleep(0.1)
    line=logFileRead.stdout.readline().strip()
    invalidIp=re.search("Invalid user \w+ from (\d*\.\d*\.\d*\.\d*)",str(line))
    if bool(invalidIp) and not bool(denyList.get(invalidIp.group(1))):
      subprocess.call("echo sshd:{}:deay >> {}".format(invalidIp.group(1),denyFile),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
      denyList[invalidIp.group(1)]=True
      nowTime=time.strftime("%Y-%m-%d %H:%M:%S")
      print("{} denyip:{} add /etc/hosts.deny".format(nowTime,invalidIp.group(1)))
      subprocess.call("echo {} denyip:{} add /etc/hosts.deny >> {}".format(nowTime,invalidIp.group(1),os.path.abspath('./log.txt')),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
    failedIp=re.search("Failed password for \w+ from ({})".format(ipPattern),str(line))
    if bool(failedIp) and not bool(denyList.get(failedIp.group(1))):
      if failedList.get(failedIp.group(1)):
        failedList[failedIp.group(1)]+=1
        if failedList[failedIp.group(1)]>advance :
          subprocess.call("echo sshd:{}:deny >> {}".format(failedIp.group(1),denyFile),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
          denyList[failedIp.group(1)]=True
          nowTime=time.strftime("%Y-%m-%d %H:%M:%S")
          print("{} denyip:{} add /etc/hosts.deny".format(nowTime,failedIp.group(1)))
          subprocess.call("echo {} denyip:{} add /etc/hosts.deny >> {}".format(nowTime,failedIp.group(1),os.path.abspath('./log.txt')),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
      else:
        failedList[failedIp.group(1)]=1
  time.sleep(5)
  monitoring()

def selectHistory():
  denyList=denyDict()
  failedList={}
  logFileRead=subprocess.Popen("cat {}".format(logFile),stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)
  logList=logFileRead.stdout.readlines()
  for line in logList:
    time.sleep(0.1)
    invalidIp=re.search("Invalid user \w+ from (\d*\.\d*\.\d*\.\d*)",str(line))
    if bool(invalidIp) and not bool(denyList.get(invalidIp.group(1))):
      subprocess.call("echo 'sshd:{}:deay' >> {}".format(invalidIp.group(1),denyFile),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
      denyList[invalidIp.group(1)]=True
      nowTime=time.strftime("%Y-%m-%d %H:%M:%S")
      print("{} denyip:{} add /etc/hosts.deny".format(nowTime,invalidIp.group(1)))
      subprocess.call("echo {} denyip:{} add /etc/hosts.deny >> {}".format(nowTime,invalidIp.group(1),os.path.abspath("./log.txt")),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
    failedIp=re.search("Failed password for \w+ from ({})".format(ipPattern),str(line))
    if bool(failedIp) and not bool(denyList.get(failedIp.group(1))):
      if failedList.get(failedIp.group(1)):
        failedList[failedIp.group(1)]+=1
        if failedList[failedIp.group(1)]>advance :
          subprocess.call("echo sshd:{}:deny >> {}".format(failedIp.group(1),denyFile),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
          denyList[failedIp.group(1)]=True
          nowTime=time.strftime("%Y-%m-%d %H:%M:%S")
          print("{} denyip:{} add /etc/hosts.deny".format(nowTime,failedIp.group(1)))
          subprocess.call("echo {} denyip:{} add /etc/hosts.deny >> {}".format(nowTime,failedIp.group(1),os.path.abspath("./log.txt")),stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
          
      else:
        failedList[failedIp.group(1)]=1

if __name__=="__main__":
  hostProcess=multiprocessing.Process(target=monitoring)
  hostProcess.start()
  checkHistory=multiprocessing.Process(target=selectHistory)
  checkHistory.start()
  hostProcess.join()
  checkHistory.join()
